﻿using Furion;
using Furion.Authorization;
using Furion.DataEncryption;
using Furion.DataValidation;
using ImageMagick;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Photo.Application.System.Role.Dto;
using Photo.Entity.System;
using Photo.Respository;
using SqlSugar;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;

namespace Photo.Web.Core;

/// <summary>
/// JWT 授权自定义处理程序
/// </summary>
public class JwtHandler : AppAuthorizeHandler
{
    /// <summary>
    /// 重写 Handler 添加自动刷新收取逻辑
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public override async Task HandleAsync(AuthorizationHandlerContext context)
    {
        // 自动刷新 token
        if (JWTEncryption.AutoRefreshToken(context, context.GetCurrentHttpContext()))
        {
            await AuthorizeHandleAsync(context);
        }
        else context.Fail();// 授权失败
    }

    /// <summary>
    /// 验证管道，也就是验证核心代码
    /// </summary>
    /// <param name="context"></param>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    public override async Task<bool> PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext)
    {
        // 检查权限，如果方法是异步的就不用 Task.FromResult 包裹，直接使用 async/await 即可
        return await CheckAuthorzie(httpContext);
    }

    /// <summary>
    /// 检查权限
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    private static async Task<bool> CheckAuthorzie(DefaultHttpContext httpContext)
    {
        // 获取权限特性
        var securityDefineAttribute = httpContext.GetMetadata<SecurityDefineAttribute>();
        if (securityDefineAttribute == null)//是否包含鉴权attribute
        {
            return true;
        }
        else
        {
            var path = httpContext.Request.Path.ToString();
            var userId = App.User?.FindFirstValue("UserId");

            var _sysUserRoleRepository = App.GetService<IRepository<SysUserRoleEntity>>();
            var _sysRoleSecurityRepository = App.GetService<IRepository<SysRoleSecurityEntity>>();

            // 解析服务
            var roleIds = await _sysUserRoleRepository.GetFieldDistinctListAsync(o => o.UserId == userId, o => o.RoleId);
            var securityList = await _sysRoleSecurityRepository.GetFieldDistinctListAsync(o => roleIds.Contains(o.RoleId), o => o.Security);

            return securityList.Contains(path);
        }
    }
}